package com.example.demo.controller;

import com.example.demo.context.BaseContext;
import com.example.demo.dto.DescriptionExpansionDTO;
import com.example.demo.dto.RoleCreateDTO;
import com.example.demo.dto.VoiceRecommendationDTO;
import com.example.demo.entity.Role;
import com.example.demo.result.Result;
import com.example.demo.service.DescriptionAssistant;
import com.example.demo.service.ImageGenerationService;
import com.example.demo.service.RoleService;
import com.example.demo.service.VoiceAssistant;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/role")
@Tag(name = "角色相关接口")
@Slf4j
public class RoleController {

    @Resource
    private RoleService roleService;
    
    @Resource
    private DescriptionAssistant descriptionAssistant;
    
    @Resource
    private VoiceAssistant voiceAssistant;
    
    @Resource
    private ImageGenerationService imageGenerationService;

    /**
     * 获取所有热门角色数据，用于首页展示
     * @return 热门角色列表
     */
    @Operation(summary = "获取热门角色列表", description = "获取所有热门角色的名称、描述和头像，用于首页展示")
    @GetMapping("/popular")
    public Result<List<Role>> getPopularRoles() {
        log.info("请求获取热门角色列表");
        return roleService.getPopularRoles();
    }

    /**
     * 根据分类获取角色列表
     * @param category 角色分类
     * @return 角色列表
     */
    @Operation(summary = "根据分类获取角色列表", description = "根据指定分类获取角色列表")
    @GetMapping("/category/{category}")
    public Result<List<Role>> getRolesByCategory(
            @Parameter(description = "角色分类", required = true)
            @PathVariable String category) {
        log.info("请求获取分类为{}的角色列表", category);
        return roleService.getRolesByCategory(category);
    }

    /**
     * 获取当前用户创建的角色
     * @return 角色列表
     */
    @Operation(summary = "获取用户创建的角色", description = "获取当前用户创建的所有角色")
    @GetMapping("/user")
    public Result<List<Role>> getRolesByUserId() {
        Long userId = BaseContext.getCurrentId();
        log.info("请求获取用户{}创建的角色列表", userId);
        return roleService.getRolesByUserId(userId);
    }

    /**
     * 根据ID获取角色详情
     * @param id 角色ID
     * @return 角色详情
     */
    @Operation(summary = "获取角色详情", description = "根据角色ID获取角色的详细信息")
    @GetMapping("/{id}")
    public Result<Role> getRoleById(
            @Parameter(description = "角色ID", required = true)
            @PathVariable Long id) {
        log.info("请求获取角色{}的详细信息", id);
        Role role = roleService.getById(id);
        if (role != null) {
            return Result.success(role);
        } else {
            return Result.error("角色不存在");
        }
    }

    /**
     * 获取所有公开角色
     * @return 所有公开角色列表
     */
    @Operation(summary = "获取所有公开角色", description = "获取系统中所有公开的角色列表")
    @GetMapping("/public")
    public Result<List<Role>> getAllPublicRoles() {
        log.info("请求获取所有公开角色列表");
        return roleService.getAllPublicRoles();
    }

    /**
     * 根据角色ID获取角色的voice配置
     * @param roleId 角色ID
     * @return 角色的voice配置
     */
    @Operation(summary = "获取角色voice配置", description = "根据角色ID获取当前用户的角色voice配置")
    @GetMapping("/voice/{roleId}")
    public Result<String> getRoleVoice(
            @Parameter(description = "角色ID", required = true)
            @PathVariable Long roleId) {
        Long userId = BaseContext.getCurrentId();
        log.info("请求获取用户{}的角色{}的voice配置", userId, roleId);
        return roleService.getRoleVoiceByRoleId(roleId);
    }

    /**
     * 根据用户ID获取其拥有的所有角色（通过用户角色关联表）
     * @param
     * @return 用户拥有的角色列表
     */
    @Operation(summary = "根据用户ID获取拥有的角色", description = "查询指定用户拥有的所有角色")
    @GetMapping("/owned")
    public Result<List<Role>> getOwnedRolesByUserId() {
        Long userId = BaseContext.getCurrentId();
        log.info("请求获取用户{}拥有的角色列表", userId);
        return roleService.getOwnedRolesByUserId(userId);
    }

    /**
     * 创建新角色
     * @param roleCreateDTO 角色创建请求
     * @return 创建的角色信息
     */
    @Operation(summary = "创建新角色", description = "用户可以创建新角色，支持AI拓写描述和声音推荐和头像生成")
    @PostMapping("/create")
    public Result<Role> createRole(@RequestBody RoleCreateDTO roleCreateDTO) {
        try {
            Long userId = BaseContext.getCurrentId();
            log.info("用户{}请求创建角色：{}", userId, roleCreateDTO.getName());
            
            // 构建角色对象
            Role role = Role.builder()
                    .name(roleCreateDTO.getName())
                    .description(roleCreateDTO.getDescription())
                    .avatar(roleCreateDTO.getAvatar())
                    .category(roleCreateDTO.getCategory())
                    .isPopular(roleCreateDTO.getIsPopular())
                    .voice(roleCreateDTO.getVoice())
                    .isPublic(roleCreateDTO.getIsPublic())
                    .userId(userId)
                    .createTime(LocalDateTime.now())
                    .updateTime(LocalDateTime.now())
                    .build();
            
            // 如果需要AI拓写描述
            if (roleCreateDTO.getNeedDescriptionExpansion() && roleCreateDTO.getDescription() != null) {
                log.info("使用AI拓写角色描述");
                String expandedDescription = descriptionAssistant.expandDescription(roleCreateDTO.getDescription());
                role.setDescription(expandedDescription);
                log.info("角色描述拓写完成，新描述长度：{}", expandedDescription.length());
            }
            
            // 获取最终的描述（可能是拓写后的描述）
            String finalDescription = role.getDescription();
            
            // 如果需要AI推荐声音（使用拓写后的描述）
            if (roleCreateDTO.getNeedVoiceRecommendation() && finalDescription != null) {
                log.info("使用AI推荐角色声音，基于{}描述", 
                    roleCreateDTO.getNeedDescriptionExpansion() ? "拓写后的" : "原始");
                String recommendedVoice = voiceAssistant.recommendVoice(finalDescription);
                role.setVoice(recommendedVoice);
                log.info("AI推荐声音：{}", recommendedVoice);
            }
            
            // 如果需要AI生成头像且当前没有头像（使用拓写后的描述）
            if (roleCreateDTO.getNeedAvatarGeneration() && 
                (role.getAvatar() == null || role.getAvatar().trim().isEmpty())) {
                log.info("使用AI生成角色头像，基于{}描述", 
                    roleCreateDTO.getNeedDescriptionExpansion() ? "拓写后的" : "原始");
                try {
                    String generatedAvatar = imageGenerationService.generateRoleAvatar(
                        role.getName(), 
                        finalDescription != null ? finalDescription : role.getName()
                    );
                    role.setAvatar(generatedAvatar);
                    log.info("角色头像生成成功：{}", generatedAvatar);
                } catch (Exception e) {
                    log.warn("角色头像生成失败，将使用默认头像：{}", e.getMessage());
                    // 头像生成失败不影响角色创建，继续执行
                }
            }
            
            // 保存角色
            boolean saved = roleService.save(role);
            if (saved) {
                log.info("角色{}创建成功，ID：{}", role.getName(), role.getId());
                return Result.success(role);
            } else {
                log.error("角色{}创建失败", role.getName());
                return Result.error("角色创建失败");
            }
        } catch (Exception e) {
            log.error("创建角色时发生异常", e);
            return Result.error("角色创建失败：" + e.getMessage());
        }
    }

    /**
     * AI描述拓写接口
     * @param expansionDTO 描述拓写请求
     * @return 拓写后的描述
     */
    @Operation(summary = "AI描述拓写", description = "使用AI对角色描述进行拓写或优化")
    @PostMapping("/expand-description")
    public Result<String> expandDescription(@RequestBody DescriptionExpansionDTO expansionDTO) {
        try {
            log.info("请求AI拓写描述，类型：{}", expansionDTO.getType());
            
            String result;
            if ("optimize".equals(expansionDTO.getType())) {
                result = descriptionAssistant.optimizeDescription(expansionDTO.getRoleInfo());
            } else {
                result = descriptionAssistant.expandDescription(expansionDTO.getRoleInfo());
            }
            
            log.info("AI描述拓写完成");
            return Result.success(result);
        } catch (Exception e) {
            log.error("AI描述拓写失败", e);
            return Result.error("描述拓写失败：" + e.getMessage());
        }
    }


    /**
     * 更新角色信息
     * @param id 角色ID
     * @param roleCreateDTO 更新的角色信息
     * @return 更新结果
     */
    @Operation(summary = "更新角色信息", description = "更新指定角色的信息")
    @PutMapping("/{id}")
    public Result<Role> updateRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id,
            @RequestBody RoleCreateDTO roleCreateDTO) {
        try {
            Long userId = BaseContext.getCurrentId();
            log.info("用户{}请求更新角色{}：{}", userId, id, roleCreateDTO.getName());
            
            // 检查角色是否存在且属于当前用户
            Role existingRole = roleService.getById(id);
            if (existingRole == null) {
                return Result.error("角色不存在");
            }
            if (!existingRole.getUserId().equals(userId)) {
                return Result.error("无权限修改此角色");
            }
            
            // 更新角色信息
            existingRole.setName(roleCreateDTO.getName());
            existingRole.setDescription(roleCreateDTO.getDescription());
            existingRole.setAvatar(roleCreateDTO.getAvatar());
            existingRole.setCategory(roleCreateDTO.getCategory());
            existingRole.setIsPopular(roleCreateDTO.getIsPopular());
            existingRole.setVoice(roleCreateDTO.getVoice());
            existingRole.setIsPublic(roleCreateDTO.getIsPublic());
            existingRole.setUpdateTime(LocalDateTime.now());
            
            // 确定最终使用的描述（可能是拓写后的描述）
            String finalDescription = existingRole.getDescription();
            
            // 如果需要AI拓写描述
            if (roleCreateDTO.getNeedDescriptionExpansion() && roleCreateDTO.getDescription() != null) {
                log.info("使用AI拓写角色描述");
                String expandedDescription = descriptionAssistant.expandDescription(roleCreateDTO.getDescription());
                existingRole.setDescription(expandedDescription);
                finalDescription = expandedDescription;
                log.info("使用拓写后的描述进行后续AI推荐");
            } else {
                log.info("使用原始描述进行后续AI推荐");
            }
            
            // 如果需要AI推荐声音，使用最终描述（优先使用拓写后的描述）
            if (roleCreateDTO.getNeedVoiceRecommendation() && finalDescription != null) {
                log.info("使用AI推荐角色声音，基于{}描述", 
                    roleCreateDTO.getNeedDescriptionExpansion() ? "拓写后的" : "原始");
                String recommendedVoice = voiceAssistant.recommendVoice(finalDescription);
                existingRole.setVoice(recommendedVoice);
            }
            
            // 保存更新
            boolean updated = roleService.updateById(existingRole);
            if (updated) {
                log.info("角色{}更新成功", existingRole.getName());
                return Result.success(existingRole);
            } else {
                log.error("角色{}更新失败", existingRole.getName());
                return Result.error("角色更新失败");
            }
        } catch (Exception e) {
            log.error("更新角色时发生异常", e);
            return Result.error("角色更新失败：" + e.getMessage());
        }
    }

    /**
     * 删除角色
     * @param id 角色ID
     * @return 删除结果
     */
    @Operation(summary = "删除角色", description = "删除指定的角色")
    @DeleteMapping("/{id}")
    public Result<String> deleteRole(
            @Parameter(description = "角色ID", required = true) @PathVariable Long id) {
        try {
            Long userId = BaseContext.getCurrentId();
            log.info("用户{}请求删除角色{}", userId, id);
            
            // 检查角色是否存在且属于当前用户
            Role existingRole = roleService.getById(id);
            if (existingRole == null) {
                return Result.error("角色不存在");
            }
            if (!existingRole.getUserId().equals(userId)) {
                return Result.error("无权限删除此角色");
            }
            
            // 删除角色
            boolean deleted = roleService.removeById(id);
            if (deleted) {
                log.info("角色{}删除成功", existingRole.getName());
                return Result.success("角色删除成功");
            } else {
                log.error("角色{}删除失败", existingRole.getName());
                return Result.error("角色删除失败");
            }
        } catch (Exception e) {
            log.error("删除角色时发生异常", e);
            return Result.error("角色删除失败：" + e.getMessage());
        }
    }
}